package com.ali.netty;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.timeout.IdleStateHandler;

import java.util.concurrent.TimeUnit;

public class NettyServer {
    public static void main(String[] args) {
        //构建连接线程池
        //构建处理线程池
        try (NioEventLoopGroup bossGroup = new NioEventLoopGroup(); NioEventLoopGroup workerGroup = new NioEventLoopGroup()) {
            //构建服务端启动对象
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            //设置线程池
            serverBootstrap.group(bossGroup, workerGroup);
            //设置通道
            serverBootstrap.channel(NioServerSocketChannel.class);
            //设置连接等待队列大小
            serverBootstrap.option(ChannelOption.SO_BACKLOG, 128);
            //设置检测连接状态
            serverBootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);
            //设置日志处理器
            serverBootstrap.handler(new LoggingHandler(LogLevel.INFO));
            //设置处理器
            serverBootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
                /**
                 * 通道初始化
                 */
                @Override
                protected void initChannel(SocketChannel socketChannel) {
                    System.out.println("initChannel方法执行");
                    //获取管道
                    ChannelPipeline channelPipeline = socketChannel.pipeline();
                    //添加空闲状态处理器，readerIdleTime(读空闲时间)，writerIdleTime(写空闲时间)，allIdleTime(读写空闲时间)
                    channelPipeline.addLast(new IdleStateHandler(3, 3, 5, TimeUnit.SECONDS));
                    //添加处理器
                    channelPipeline.addLast(new MyServerHandler());
                }
            });
            //绑定监听端口，同步阻塞，等待操作完成
            ChannelFuture channelFuture = serverBootstrap.bind(8080).sync();
            //添加监听器
            channelFuture.addListener(new ChannelFutureListener() {
                /**
                 * 操作完成
                 */
                @Override
                public void operationComplete(ChannelFuture channelFuture) {
                    if (channelFuture.isSuccess()) {
                        System.out.println("绑定监听端口成功");
                    } else {
                        System.out.println("绑定监听端口失败");
                    }
                }
            });
            //监听关闭通道，同步阻塞，等待操作完成
            channelFuture.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}
